package com.zjj.wangluo.tcp;


import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 * @author zhoujunjie
 * @desc TODO
 * @date
 */
public class TCPServer {

    //线程池
    private static final ThreadPool pool = new ThreadPool(PoolConfig.MAX_POOL_SIZE , PoolConfig.QUEUE_SIZE);
    //至多执行的任务数
    private static final int MAX_CLIENTS = PoolConfig.MAX_POOL_SIZE  + PoolConfig.QUEUE_SIZE;

    public static void main(String[] args) {
        System.out.println("--------- TCPServer ----------");
        //线程安全的集合  存储所有接入的客户端
        CopyOnWriteArrayList<Socket> clients = new CopyOnWriteArrayList<>();

        ServerSocket ss = null;
        try {
            ss = new ServerSocket(8888);
            while (true){
                Socket socket = ss.accept();
                //将当前接入的客户端套接字存储至容器中，方便后面进行转发消息
                clients.add(socket);

                //话务员  为每一个接入的客户端，创建一个话务员维系之间的通信
                ServerTasker tasker = new ServerTasker(socket , clients , Thread.currentThread());
                pool.exec(tasker);
                System.out.println(socket.getRemoteSocketAddress() +"已上线~");

                //一旦达到极限，不再接入客户端
                if(clients.size() == MAX_CLIENTS){
                    ss.close();
                    ss = null;
                    //阻塞当前线程  main主线程
                    LockSupport.park();
                    //确保由足够的时间，将线程归还至线程池中
                    try {
                        TimeUnit.MILLISECONDS.sleep(500);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    ss = new ServerSocket(8888);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if(ss!=null){
                try {
                    ss.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

}
